package com.lavida.project.system.user.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import com.lavida.project.system.role.domain.Role;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lavida.common.constant.UserConstants;
import com.lavida.common.utils.StringUtils;
import com.lavida.common.utils.poi.ExcelUtil;
import com.lavida.common.utils.security.ShiroUtils;
import com.lavida.framework.aspectj.lang.annotation.Log;
import com.lavida.framework.aspectj.lang.enums.BusinessType;
import com.lavida.framework.web.controller.BaseController;
import com.lavida.framework.web.domain.AjaxResult;
import com.lavida.framework.web.page.TableDataInfo;
import com.lavida.project.system.dept.mapper.DeptMapper;
import com.lavida.project.system.post.service.IPostService;
import com.lavida.project.system.role.service.IRoleService;
import com.lavida.project.system.user.domain.User;
import com.lavida.project.system.user.domain.UserRole;
import com.lavida.project.system.user.mapper.UserMapper;
import com.lavida.project.system.user.mapper.UserRoleMapper;
import com.lavida.project.system.user.service.IUserService;

/**
 * 用户信息
 * 
 */
@Controller
@RequestMapping("/system/user")
public class UserController extends BaseController {
	private String prefix = "system/user";

	@Autowired
	private IUserService userService;

	@Autowired
	private IRoleService roleService;

	@Autowired
	private IPostService postService;

	@Autowired
	private DeptMapper deptMapper;

	@Autowired
	private UserMapper userMapper;

	@RequiresPermissions("system:user:view")
	@GetMapping()
	public String user(ModelMap mmap) {
		User user  = ShiroUtils.getSysUser();
		User user1 = userService.selectUserById(user.getUserId());
		mmap.put("user", user1);
		System.out.println("====================访问user");
		return prefix + "/user";
	}

	//@RequiresPermissions("system:user:list")
	@PostMapping("/list")
	@ResponseBody
	public TableDataInfo list(User user) {
		startPage();
		List<User> list = userService.selectUserList(user);
		System.out.println("list=" + list);
		return getDataTable(list);
	}

	@Log(title = "用户管理", businessType = BusinessType.EXPORT)
	@RequiresPermissions("system:user:export")
	@PostMapping("/export")
	@ResponseBody
	public AjaxResult export(User user) {
		List<User> list = userService.selectUserList(user);
		ExcelUtil<User> util = new ExcelUtil<User>(User.class);
		return util.exportExcel(list, "用户数据");
	}

	@Log(title = "用户管理", businessType = BusinessType.IMPORT)
	@RequiresPermissions("system:user:import")
	@PostMapping("/importData")
	@ResponseBody
	public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
		ExcelUtil<User> util = new ExcelUtil<User>(User.class);
		List<User> userList = util.importExcel(file.getInputStream());
		String message = userService.importUser(userList, updateSupport);
		return AjaxResult.success(message);
	}

	@RequiresPermissions("system:user:view")
	@GetMapping("/importTemplate")
	@ResponseBody
	public AjaxResult importTemplate() {
		ExcelUtil<User> util = new ExcelUtil<User>(User.class);
		return util.importTemplateExcel("用户数据");
	}

	/**
	 * 新增用户
	 */
	//@RequiresPermissions("system:user:add")
	@GetMapping("/add")
	@ResponseBody
	public String add(ModelMap mmap) {
		return prefix+"/add";
	}

	/**
	 * 新增保存用户
	 */
	@RequiresPermissions("system:user:add")
	@Log(title = "用户管理", businessType = BusinessType.INSERT)
	@PostMapping("/add")
	@ResponseBody
	public AjaxResult addSave(@Validated User user) {
		if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user.getLoginName()))) {
			return error("新增用户'" + user.getLoginName() + "'失败，登录账号已存在");
		} else if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
			return error("新增用户'" + user.getLoginName() + "'失败，手机号码已存在");
		} else if (UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
			return error("新增用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
		}
		// 该部门已经有部门领导，不允许新增
		else if (Arrays.asList(user.getRoleIds()).contains(100L)
				&& StringUtils.isNotBlank(userMapper.selectDeptLeaderId("deptLeader", user.getDeptId()))) {
			return error("新增用户'" + user.getLoginName() + "'失败，该部门已经有一位用户的角色为部门领导");
		}
		
		return toAjax(userService.insertUser(user));
	}

	/**
	 * 修改用户
	 */
	@RequiresPermissions("system:user:edit")
	@GetMapping("/edit/{userId}")
	public String edit(@PathVariable("userId") Long userId, ModelMap mmap) {
		mmap.put("user", userService.selectUserById(userId));
		mmap.put("depts", deptMapper.selectDeptAll());
		mmap.put("roles", roleService.selectRolesByUserId(userId));
		mmap.put("posts", postService.selectPostsByUserId(userId));
		
		return prefix + "/edit";
	}

	/**
	 * 修改保存用户
	 */
	@RequiresPermissions("system:user:edit")
	@Log(title = "用户管理", businessType = BusinessType.UPDATE)
	@PostMapping("/edit")
	@ResponseBody
	public AjaxResult editSave(@Validated User user) {
		userService.checkUserAllowed(user);
		if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
			return error("修改用户'" + user.getLoginName() + "'失败，手机号码已存在");
		} else if (UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
			return error("修改用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
		}
		// 该部门已经有部门领导，不是本人，不允许修改
		String deptLeader = userMapper.selectDeptLeaderId("deptLeader", user.getDeptId());
		if (Arrays.asList(user.getRoleIds()).contains(100L) && StringUtils.isNotBlank(deptLeader)
				&& !user.getLoginName().equals(deptLeader)) {
			return error("修改用户'" + user.getLoginName() + "'失败，该部门已经有一位用户的角色为部门领导");
		}
		return toAjax(userService.updateUser(user));
	}

	/*
	 * @RequiresPermissions("system:user:resetPwd")
	 * 
	 * @Log(title = "重置密码", businessType = BusinessType.UPDATE)
	 * 
	 * @GetMapping("/resetPwd/{userId}") public String
	 * resetPwd(@PathVariable("userId") Long userId, ModelMap mmap) {
	 * mmap.put("user", userService.selectUserById(userId)); return prefix +
	 * "/resetPwd"; }
	 */

	@RequiresPermissions("system:user:resetPwd")
	@Log(title = "重置密码", businessType = BusinessType.UPDATE)
	@GetMapping("/resetPwd/{userId}")
	@ResponseBody
	public Map<String, Object> resetPwd(@PathVariable("userId") Long userId, ModelMap mmap) {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("user", userService.selectUserById(userId));
		return result;
	}

	@RequiresPermissions("system:user:resetPwd")
	@Log(title = "重置密码", businessType = BusinessType.UPDATE)
	@PostMapping("/resetPwd")
	@ResponseBody
	public AjaxResult resetPwdSave(User user) {
		userService.checkUserAllowed(user);
		if (userService.resetUserPwd(user) > 0) {
			if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue()) {
				setSysUser(userService.selectUserById(user.getUserId()));
			}
			return success();
		}
		return error();
	}

	/**
	 * 进入授权角色页
	 */
	@GetMapping("/authRole/{userId}")
	public String authRole(@PathVariable("userId") Long userId, ModelMap mmap) {
		User user = userService.selectUserById(userId);
		// 获取用户所属的角色列表
		List<UserRole> userRoles = userService.selectUserRoleByUserId(userId);
		mmap.put("user", user);
		mmap.put("userRoles", userRoles);
		return prefix + "/authRole";
	}

	/**
	 * 用户授权角色
	 */
	@RequiresPermissions("system:user:add")
	@Log(title = "用户管理", businessType = BusinessType.GRANT)
	@PostMapping("/authRole/insertAuthRole")
	@ResponseBody
	public AjaxResult insertAuthRole(Long userId, Long[] roleIds) {
		userService.insertUserAuth(userId, roleIds);
		return success();
	}

	@RequiresPermissions("system:user:remove")
	@Log(title = "用户管理", businessType = BusinessType.DELETE)
	@PostMapping("/remove")
	@ResponseBody
	public AjaxResult remove(String ids) {
		try {
			return toAjax(userService.deleteUserByIds(ids));
		} catch (Exception e) {
			return error(e.getMessage());
		}
	}
	/**
	 * 校验用户名
	 */
	@PostMapping("/checkLoginNameUnique")
	@ResponseBody
	public String checkLoginNameUnique(User user) {
		return userService.checkLoginNameUnique(user.getLoginName());
	}

	/**
	 * 校验手机号码
	 */
	@PostMapping("/checkPhoneUnique")
	@ResponseBody
	public String checkPhoneUnique(User user) {
		return userService.checkPhoneUnique(user);
	}

	/**
	 * 校验email邮箱
	 */
	@PostMapping("/checkEmailUnique")
	@ResponseBody
	public String checkEmailUnique(User user) {
		return userService.checkEmailUnique(user);
	}

	/**
	 * 用户状态修改
	 */
	@Log(title = "用户管理", businessType = BusinessType.UPDATE)
	@RequiresPermissions("system:user:edit")
	@PostMapping("/changeStatus")
	@ResponseBody
	public AjaxResult changeStatus(User user) {
		userService.checkUserAllowed(user);
		return toAjax(userService.changeStatus(user));
	}
	/**
	 * 	删除用户
	 * @param userId
	 * @return
	 */
	@RequestMapping("/deleteUser")
	@ResponseBody
	public Map<String, String> deleteUser(int userId) {
		Map<String, String> result = new HashMap<>();
		userService.deleteUser(userId);
		result.put("msg", "删除成功");
		return result;
	}
	//
	@RequestMapping("//addUserConfirm")
	@ResponseBody
	public boolean addUserconfirm(String loginName) {
		User user2 = userService.selectByLoginName(loginName.trim());
		if(user2!=null) {
			return false;
		}
		return true;
	}
	@RequestMapping("/addUser")
	@ResponseBody
	public Map<String, Object> addUser(User user,String comfirmPwd,HttpServletRequest request,@RequestParam("roleIdss[]")Long[] roleIdss) {
		String loginName = request.getParameter("loginName");
		String userName = request.getParameter("userName");
		String password = request.getParameter("password");
		String createTime = request.getParameter("createTime");
		System.out.println("user>>>>>>>>>>>>>>>>>>>"+user.toString());
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		Map<String, Object> message = new HashMap<>();
		String result = null;
		String msg = null;
		try {
			date = sdf.parse(createTime);
		} catch (ParseException e) {
			message.put("status", "23");
			e.printStackTrace();
		}
			user.setLoginName(loginName);
			user.setUserName(userName);
			user.setCreateTime(date);
			String salt = UUID.randomUUID().toString();
			String passwordMD5 = new Md5Hash(loginName + password + salt).toHex();
			user.setPassword(passwordMD5);
			user.setSalt(salt);
			String userm ="";
			for(int i=0;i<roleIdss.length;i++) {
				 Role role = roleService.selectRoleById(roleIdss[i]);
				 if(i!=roleIdss.length-1) {
					 userm = userm + role.getRoleName()+",";
				 }else {
					 userm = userm + role.getRoleName();
				 }	
			}
			user.setRole(userm);
			userService.addUser(user);
			Long userId = userService.selectByLoginNames(loginName);
			userService.batchUserRoles(userId, roleIdss);
			message.put("msg", "");
			message.put("status", "20");
			return message;
	}
	/**
	 * 修改用户密码
	 */
	@RequestMapping("/updatePwd")
	@ResponseBody
	public Map<String, Object> updatePwd(Integer userIdGolbal,String newPassword,String confirmPassword) {
		User user = userService.selectUser(userIdGolbal);
		Map<String, Object> result = new HashMap<>();
		String passwordMd5 = new Md5Hash(user.getLoginName()+newPassword.trim()+user.getSalt()).toHex();
		try {
			userService.updateUserPwd(passwordMd5, userIdGolbal);
			result.put("status", 20);
			result.put("msg", "密码更新成功");
			return result;

		} catch (Exception e) {
			result.put("status", 21);
			result.put("msg", "密码更新失败");
			return result;
		}
	}
	@RequestMapping("/updateRole")
	@ResponseBody
	public Map<String, String> updateRole(String role,Integer userId){
		Map<String, String> result = new HashMap<>();
		userService.updateUserRole(role, userId);
		result.put("msg", "角色修改成功");
		return result;
	}
	
}